package com.sketch.controller;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.internal.util.AlipaySignature;
import com.sketch.commom.Result;
import com.sketch.commom.config.properties.AliProperties;
import com.sketch.commom.config.properties.WechatProperties;
import com.sketch.entity.RechargeRecord;
import com.sketch.service.PayServer;
import com.sketch.service.RechargeRecordService;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.exception.ValidationException;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.service.payments.model.Transaction;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Map;

@Api(tags = "支付接口 API")
@RestController
@RequestMapping(value = "/api/pay")
@Slf4j
public class PayController {

    @Resource
    private PayServer payServer;

    @Autowired
    private AliProperties aliProperties;

    @Autowired
    private WechatProperties wechatProperties;

    @Autowired
    private RechargeRecordService rechargeRecordService;

    /**
     * 详情
     */
    @GetMapping("/payOrder")
    @ApiOperation("支付接口")
    public Result<Void> pay(@ApiParam(value = "VIPId")
                            @RequestParam(value = "vipId", defaultValue = "1") Long vipId, @ApiParam(value = "支付类型 1 支付宝 2微信")
                            @RequestParam(value = "payType", defaultValue = "1") Integer payType) {
        RechargeRecord entity = rechargeRecordService.add(vipId);
        if(payType==2){
            payServer.weChatPay(entity.getOutTradeNo().toString(), entity.getTitle(), entity.getPrice().toString());
        }else {
            payServer.aliPay(entity.getOutTradeNo().toString(), entity.getTitle(), entity.getPrice().toString());
        }
        return Result.success();
    }

    /**
     * 详情
     * https://www.merchant.com/receive_notify.htm?notify_type=trade_status_sync&
     * notify_id=91722adff935e8cfa58b3aabf4dead6ibe&
     * notify_time=2017-02-16 21:46:15&
     * sign_type=RSA2&sign=WcO+t3D8Kg71dTlKwN7r9PzUOXeaBJwp8/FOuSxcuSkXsoVYxBpsAidprySCjHCjmaglNcjoKJQLJ28/Asl93joTW39FX6i07lXhnbPknezAlwmvPdnQuI01HZsZF9V1i6ggZjBiAd5lG8bZtTxZOJ87ub2i9GuJ3Nr/NUc9VeY=&out_channel_type=null&trade_no=null&app_id=null&out_trade_no=null&seller_id=null&trade_status=null&total_amount=null&refund_fee=null&subject=null&body=null&gmt_create=null&gmt_payment=null&gmt_refund=null&gmt_close=null&buyer_id=null&fund_bill_list=[{"amount":"50.00","fundChannel":"ALIPAYACCOUNT"}]&
     * receipt_amount=null&invoice_amount=null&buyer_pay_amount=null&point_amount=null&voucher_detail_list=null
     * &buyer_logon_id=null&seller_email=null&out_biz_no=null&passback_params=null
     * &notify_action_type=payByAccountAction/closeTradeAction/reverseAction/finishFPAction/confirmDisburseAction/financingReceiptAction&current_seller_received_amount=88.88&seller_received_total_amount=88.88&total_from_seller_fee=88.88&ff_current_period=1&discount_amount=88.88&charge_amount=8.88&charge_flags=bluesea_1&settlement_id=2018101610032004620239146945&industry_sepc_detail={"registration_order_pay":{"brlx":"1","cblx":"1"}}&industry_sepc_detail_acc={"registration_order_pay":{"brlx":"1","cblx":"1"}}&industry_sepc_detail_gov={"registration_order_pay":{"brlx":"1","cblx":"1"}}&discount_goods_detail="[{\"goodsId\":\"STANDARD1026181538\",\"goodsName\":\"雪碧\",\"discountAmount\":\"10.00\"}]"&mdiscount_amount=88.88&hb_fq_pay_info={"USER_INSTALL_NUM":"3"}&receipt_currency_type=DC&enterprise_pay_info={"invoice_amount":"28.00","is_use_enterprise_pay":"true"}&hyb_amount=10.24&charge_info_list=[{"charge_fee":"0.01","original_charge_fee":"0.02","switch_fee_rate":"0.03","is_rating_on_trade_receiver":"Y","is_rating_on_switch":"Y"}]&medical_insurance_info={"medicareCardType":"1","medicareCardHolderHiddenName":"**专"}&credit_pay_mode=creditAdvanceV2&buyer_charge_amt=1.00&fulfillment_amount=10.24
     */
    @GetMapping("/notify")
    @ApiOperation("支付宝回调接口")
    public Result<JSONObject> notify(@RequestParam Map<String, String> params) {
        try {
            // 1.日志记录
            log.info("####支付宝同步通知synCallBack####开始,params:{}", params);
            // 2.验签操作
            boolean signVerified = AlipaySignature.rsaCheckV1(params, aliProperties.getPublicKey(),
                    aliProperties.getCharset(), aliProperties.getSignType()); // 调用SDK验证签名

            log.info("####支付参数验签signVerified:{}####", signVerified);
            // ——请在这里编写您的程序（以下代码仅作参考）——
            if (!signVerified) {
                return Result.error("验签失败");
            }
            // 商户订单号
            String outTradeNo = params.get("out_trade_no");
            // 支付宝交易号
            // 付款金额
            String totalAmount = params.get("totalAmount");
            String trade_status = params.get("trade_status");
            Integer paystatus = 0;
            if ("TRADE_SUCCESS".equals(trade_status)) {
                //交易支付成功。
                paystatus = 0;
            }
            if ("TRADE_CLOSED".equals(trade_status)) {
                //未付款交易超时关闭，或支付完成后全额退款
                paystatus = 1;
            }
            rechargeRecordService.update(outTradeNo, paystatus);

            return Result.success();
        } catch (Exception e) {
            log.error("####支付宝支付异常####,异常原因:{}", e);
            return Result.error("系统错误");
        }
    }

    /**
     * https://pay.weixin.qq.com/docs/merchant/apis/in-app-payment/payment-notice.html
     * 订单回调接口
     */
    @ApiOperation("微信支付回调")
    @PostMapping("/callBack")
//    public ResponseEntity.BodyBuilder callBack(@RequestBody TransactionsEntity entity, HttpServletResponse response) {
    public ResponseEntity<String> callBack(@RequestBody com.wechat.pay.java.core.notification.RequestParam requestParam) {

//        com.wechat.pay.java.core.notification.RequestParam requestParam = new com.wechat.pay.java.core.notification.RequestParam.Builder()
//                .serialNumber("1DDE55AD98ED71D6EDD4A4A16996DE7B47773A8C")
//                .nonce("593BEC0C930BF1AFEB40B4A08C8FB242")
//                .signature("uOVRnA4qG/MNnYzdQxJanN+zU+lTgIcnU9BxGw5dKjK+VdEUz2FeIoC+D5sB/LN+nGzX3hfZg6r5wT1pl2ZobmIc6p0ldN7J6yDgUzbX8Uk3sD4a4eZVPTBvqNDoUqcYMlZ9uuDdCvNv4TM3c1WzsXUrExwVkI1XO5jCNbgDJ25nkT/c1gIFvqoogl7MdSFGc4W4xZsqCItnqbypR3RuGIlR9h9vlRsy7zJR9PBI83X8alLDIfR1ukt1P7tMnmogZ0cuDY8cZsd8ZlCgLadmvej58SLsIkVxFJ8XyUgx9FmutKSYTmYtWBZ0+tNvfGmbXU7cob8H/4nLBiCwIUFluw==")
//                .signature("3284e3e0b44973daed93ab94a463f0dfe70f320e")
//                .timestamp("1554208460")
//                .body("{\"data\":[{\"serial_no\":\"1DDE55AD98ED71D6EDD4A4A16996DE7B47773A8C\",\"effective_time\":\"2020-03-22T11:39:50+08:00\",\"expire_time\":\"2025-03-25T11:39:50+08:00\",\"encrypt_certificate\":{\"algorithm\":\"AEAD_AES_256_GCM\",\"nonce\":\"4de73afd28b6\",\"associated_data\":\"certificate\",\"ciphertext\":\"...\"}}]}")
//                .build();

        // 如果已经初始化了 RSAAutoCertificateConfig，可直接使用
        // 没有的话，则构造一个
        NotificationConfig config =
                new RSAAutoCertificateConfig.Builder()
                        .merchantId(wechatProperties.getMerchantId())
                        .privateKeyFromPath(this.getClass().getClassLoader().getResource(wechatProperties.getPrivateKeyPath()).getPath())
                        .merchantSerialNumber(wechatProperties.getMerchantSerialNumber())
                        .apiV3Key(wechatProperties.getApiV3Key())
                        .build();

        // 初始化 NotificationParser
        NotificationParser parser = new NotificationParser(config);
        try {
            // 以支付通知回调为例，验签、解密并转换成 Transaction
            Transaction transaction = parser.parse(requestParam, Transaction.class);
            String outTradeNo = transaction.getOutTradeNo();
            Transaction.TradeStateEnum tradeState = transaction.getTradeState();
            int paystatus = 1;
            if (Transaction.TradeStateEnum.SUCCESS.equals(tradeState)) {
                paystatus = 0;
            }
            int i = rechargeRecordService.update(outTradeNo, paystatus);
            if (i > 0) {
                return ResponseEntity.status(HttpStatus.OK).build();
            } else {
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("{  \n" +
                        "    \"code\": \"FAIL\",\n" +
                        "    \"message\": \"失败\"\n" +
                        "}");
            }

        } catch (ValidationException e) {
            // 签名验证失败，返回 401 UNAUTHORIZED 状态码
            log.error("sign verification failed", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("{  \n" +
                    "    \"code\": \"FAIL\",\n" +
                    "    \"message\": \"失败\"\n" +
                    "}");
        }
    }
}
